﻿#include "mediadevicedialog.h"
#include "ui_mediadevicedialog.h"
#include <QTimer>
#include <vector>
#include <libmedia.h>
#include "clientcallback.h"
#include "globaltools.h"
#include "usersettings.h"

static const int MediaDevice_Timer_Interval = 200;

void AudioVolume::stopAudioTimer()
{
    volume=-1;
    timer_count=-1;
    if(bar)
    {
        bar->setValue(0);
        bar->setStyleSheet(QString());
        bar->setFormat(QObject::trECSUTF8("无数据"));
    }
}

void AudioVolume::handle_volume(int vol)
{
    volume = qBound(0,qMax(volume,vol),100);
    if(timer_count<0)
    {
        if(bar)
        {
            bar->setStyleSheet(QLatin1String("background-color: greenyellow;"));
            bar->setValue(volume);
            bar->setFormat(QObject::trECSUTF8("正常"));
        }
        timer_count = 0;
    }
}

void AudioVolume::handle_timer_event()
{
    if(timer_count>=0)
    {
        timer_count+=MediaDevice_Timer_Interval;
        if(timer_count>=200)
        {
            if(volume<0)
            {
                if(timer_count>5*200)
                    stopAudioTimer();
            }
            else
            {
                if(bar)
                    bar->setValue(volume);
                volume = -1;
                timer_count = 0;
            }
        }
    }
}

MediaDeviceDialog::MediaDeviceDialog(QWidget *parent) :
    QDialog(parent,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint | Qt::MSWindowsFixedSizeDialogHint),
    ui(new Ui::MediaDeviceDialog),
    deviceIndexVideo(-1),deviceIndexPhone(-1),deviceIndexSpeaker(-1),
    video_channel_id_(-1),phone_channel_id_(-1),speaker_channel_id_(-1),
    video_timer_count(-1),phone_volume(ui->bar_input),speaker_volume(ui->bar_output)

{
	video_channel_id_ = -1;

    ui->setupUi(this);

    ui->viewFinder->setFixedSize(320,240);

    const QString str_disable = QObject::trECSUTF8("禁用");
    const QByteArray empty("");

	device_module_base* engine = device_module_base::get();
	const int max_device_cnt = 16;
	device_desc device_list[max_device_cnt];

	int device_cnt = engine->list_cameras(device_list, max_device_cnt);
    ui->combo_camera->setItemData(0, empty);
    for(int i = 0; i<device_cnt; i++)
    {
        ui->combo_camera->addItem(QString::fromLocal8Bit(device_list[i].name), device_list[i].index);
    }
    ui->combo_camera->addItem(QObject::trECSUTF8("虚拟模式"),virtualCameraId);
    ui->combo_camera->addItem(str_disable,-1);	

	device_cnt = engine->list_microphones(device_list, max_device_cnt);
    ui->combo_input->setItemData(0, empty);
    for (int i = 0; i<device_cnt; i++)
	{
        ui->combo_input->addItem(QString::fromLocal8Bit(device_list[i].name), device_list[i].index);
	}
	ui->combo_input->addItem(str_disable, -1);

	device_cnt = engine->list_speakers(device_list, max_device_cnt);
    ui->combo_output->setItemData(0, empty);
    for (int i = 0; i<device_cnt; i++)
    {
        ui->combo_output->addItem(QString::fromLocal8Bit(device_list[i].name), device_list[i].index);
    }
    ui->combo_output->addItem(str_disable,-1);

    bool save = false;
    auto settings = UserSettings::instance();
    QVariant var = settings->getValue(UserSettings::sys_video_index);
    bool ok = false;
    int idx = -1;
    deviceIndexVideo = var.toInt(&ok);
    if(!var.isValid())
    {
        settings->setValue(UserSettings::sys_video_index, empty);
        save = true;
    }
    else if(ok)
    {
        idx = ui->combo_camera->findData(deviceIndexVideo);
        if(idx>=0)
            ui->combo_camera->setCurrentIndex(idx);
    }

    var = settings->getValue(UserSettings::sys_mic_index);
    deviceIndexPhone = var.toInt(&ok);
    if(!var.isValid())
    {
        settings->setValue(UserSettings::sys_mic_index, empty);
        save = true;
    }
    else if(ok)
    {
        idx = ui->combo_input->findData(deviceIndexPhone);
        if(idx>=0)
            ui->combo_input->setCurrentIndex(idx);
    }

    var = settings->getValue(UserSettings::sys_speaker_index);
    deviceIndexSpeaker = var.toInt(&ok);
    if(!var.isValid())
    {
        settings->setValue(UserSettings::sys_speaker_index, empty);
        save = true;
    }
    else if(ok)
    {
        idx = ui->combo_output->findData(deviceIndexSpeaker);
        if(idx>=0)
            ui->combo_output->setCurrentIndex(idx);
    }
    if(save)
        settings->save_system_setting();

    connect(ui->combo_camera,SIGNAL(currentIndexChanged(int)),SLOT(slot_combo_camera_currentIndexChanged(int)),Qt::QueuedConnection);
    connect(ui->combo_input,SIGNAL(currentIndexChanged(int)),SLOT(slot_combo_input_currentIndexChanged(int)),Qt::QueuedConnection);
    connect(ui->combo_output,SIGNAL(currentIndexChanged(int)),SLOT(slot_combo_output_currentIndexChanged(int)),Qt::QueuedConnection);

    bool ret = connect(ClientCallback::instance(),SIGNAL(signal_video_test(QPixmap)),
                  SLOT(slot_video_test(QPixmap)));
    ret = connect(ClientCallback::instance(),SIGNAL(signal_phone_test(int)),
                  SLOT(slot_phone_test(int)));
    ret = connect(ClientCallback::instance(),SIGNAL(signal_speaker_test(int)),
                  SLOT(slot_speaker_test(int)));

    phone_volume.stopAudioTimer();
    speaker_volume.stopAudioTimer();
    timer.start(MediaDevice_Timer_Interval, this);
    QTimer::singleShot(100,this,SLOT(slot_start()));
}

MediaDeviceDialog::~MediaDeviceDialog()
{
	if (video_channel_id_ >= 0)
	{
        ClientCallback::instance()->stop_camera_test();
	}
	if (phone_channel_id_ >= 0)
	{
        ClientCallback::instance()->stop_microphone_test();
	}
        
	if (speaker_channel_id_ >= 0)
	{
        ClientCallback::instance()->stop_speaker_test();
	}
       
    delete ui;

}

void MediaDeviceDialog::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == timer.timerId())
    {
        phone_volume.handle_timer_event();
        speaker_volume.handle_timer_event();
        if(video_timer_count>=0)
        {
            int interval = 5*200;
            if((video_timer_count+=MediaDevice_Timer_Interval)>=interval)
            {
                video_timer_count=-1;
                ui->viewFinder->clear();
            }
        }
    }
    return QDialog::timerEvent(e);
}

void MediaDeviceDialog::slot_combo_output_currentIndexChanged(int index)
{
    QVariant varCur = ui->combo_output->currentData();
    auto settings = UserSettings::instance();
    if (settings->setValueIfChanged(UserSettings::sys_speaker_index, varCur))
        settings->save_system_setting();

    int device_id = varCur.toInt();
    if(deviceIndexSpeaker == device_id)
        return;

    deviceIndexSpeaker = device_id;
    ClientCallback::instance()->set_speaker_id(device_id);
    speaker_volume.stopAudioTimer();

}

void MediaDeviceDialog::slot_combo_input_currentIndexChanged(int index)
{
    QVariant varCur = ui->combo_input->currentData();
    auto settings = UserSettings::instance();
    if (settings->setValueIfChanged(UserSettings::sys_mic_index, varCur))
        settings->save_system_setting();

    int device_id = varCur.toInt();
    if(deviceIndexPhone == device_id)
        return;

    deviceIndexPhone = device_id;
    ClientCallback::instance()->set_microphone_id(device_id);
    ClientCallback::instance()->setAudioInput(device_id);
    phone_volume.stopAudioTimer();
}

void MediaDeviceDialog::slot_combo_camera_currentIndexChanged(int index)
{    
    QVariant varCur = ui->combo_camera->currentData();
    auto settings = UserSettings::instance();
    if (settings->setValueIfChanged(UserSettings::sys_video_index, varCur))
        settings->save_system_setting();

    int device_id = varCur.toInt();
    if(deviceIndexVideo == device_id)
        return;

    deviceIndexVideo = device_id;
    ClientCallback::instance()->set_camera_id(device_id);
    video_timer_count=-1;
    ui->viewFinder->clear();
}

void MediaDeviceDialog::slot_video_test(QPixmap pix)
{
    ui->viewFinder->setPixmap(pix);
    video_timer_count = 0;
}

void MediaDeviceDialog::slot_phone_test(int volume)
{
    phone_volume.handle_volume(volume);
}

void MediaDeviceDialog::slot_speaker_test(int volume)
{
    speaker_volume.handle_volume(volume);
}

void MediaDeviceDialog::slot_start()
{
    video_channel_id_ = 1;
    speaker_channel_id_ = 1;
    phone_channel_id_ = 1;
    auto ccb = ClientCallback::instance();
    ccb->start_camera_test();
    ccb->start_speaker_test();
    ccb->start_microphone_test();
}
